// evmone: Fast Ethereum Virtual Machine implementation
// Copyright 2023 The evmone Authors.
// SPDX-License-Identifier: Apache-2.0

#include <evmc/evmc.hpp>
#include <gtest/gtest.h>
#include <test/state/bloom_filter.hpp>
#include <test/state/state.hpp>
#include <test/utils/utils.hpp>
#include <array>

using namespace evmc::literals;
using namespace evmone::state;
using namespace evmone::test;

TEST(state_bloom_filter, combine_blooms)
{
    // https://sepolia.etherscan.io/block/2946594

    const auto block_bloom =
        "000000000000000000000000800000000000000000000002000000000000000000000000000000000000008000"
        "000000000000000000000000000040000000000000000000000000000000200010000000000000000000004000"
        "0000000000000000000040000000000000000000000000000000000000000000000000000000000000000c0000"
        "200800000000000000000000000000000000000000000000000000800000000000000000000000000000000000"
        "000000000000000000000040000004000000000000000020020000000000000000000000060000000000000000"
        "00000002000000000000000000000000000000000000010000000000000000"_hex;

    const auto bloom_1 =
        "000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000"
        "000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000"
        "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000"
        "200800000000000000000000000000000000000000000000000000800000000000000000000000000000000000"
        "000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000"
        "00000002000000000000000000000000000000000000000000000000000000"_hex;

    const auto bloom_2 =
        "000000000000000000000000800000000000000000000002000000000000000000000000000000000000000000"
        "000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000"
        "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000"
        "200800000000000000000000000000000000000000000000000000800000000000000000000000000000000000"
        "000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000"
        "00000000000000000000000000000000000000000000000000000000000000"_hex;

    const auto bloom_4 =
        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000"
        "000000000000000000000000000000000000000000000000000000000000000010000000000000000000004000"
        "000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000"
        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        "000000000000000000000000000004000000000000000020000000000000000000000000060000000000000000"
        "00000000000000000000000000000000000000000000010000000000000000"_hex;

    TransactionReceipt r1;
    r1.logs_bloom_filter = bloom_filter_from_bytes(bloom_1);
    TransactionReceipt r2;
    r2.logs_bloom_filter = bloom_filter_from_bytes(bloom_2);
    TransactionReceipt r4;
    r4.logs_bloom_filter = bloom_filter_from_bytes(bloom_4);

    const std::array receipts{r1, r2, r4};
    const auto res = compute_bloom_filter(receipts);
    EXPECT_EQ(bytes_view(res), block_bloom);
}

TEST(state_bloom_filter, combine_blooms_simgle_transaction)
{
    // https://sepolia.etherscan.io/tx/0xe07740662828a58224e2efedf3accd2763ae52c5b281b120019c3b4a0b6862dd

    const auto expected_result =
        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000"
        "000000000000000000000000000000000000000000000000000000000000000010000000000000000000004000"
        "000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000"
        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        "000000000000000000000000000004000000000000000020000000000000000000000000060000000000000000"
        "00000000000000000000000000000000000000000000010000000000000000"_hex;

    const Log log{0x6e397a41f9fa7362e2c726bff032b4cd3fbc0b3c_address, {},
        {0x01a1249f2caa0445b8391e02413d26f0d409dabe5330cd1d04d3d0801fc42db3_bytes32,
            0x497f3c9f61479c1cfa53f0373d39d2bf4e5f73f71411da62f1d6b85c03a60735_bytes32}};

    const std::array logs{log};
    const auto res = compute_bloom_filter(logs);
    EXPECT_EQ(bytes_view(res), expected_result);
}
